• unsupervised(비지도)와 supervised(지도)의 차이는 y가 있느냐 없느냐의 차이. 답이 있느냐 없느냐의 차이다.

    • 학습에 사용되는 데이터에 결과가 정해졌 있는 경우를 Supervised Learning이라고 한다.
    • 예를 들어, “아파트 평수가 22평일 때, 구매 가격이 1억이다”와 같은 경우인데, “구매가격이 1억이다”라는 결과 값이 정해져있는 경우이다.
    • 반대로, 영화관 관람객 데이터가 있을 때, “20대x30 명, 30대x10명,40대x10명”과 같이 어떤 데이터데 대해서 그 결과값이 없을 경우에는 비지도 학습(Un-supervised learning이라고 한다)
    • 이처럼 비지도 학습(Unsupervised learning)이란, Training data에 target value가 없는 경우를 말한다. 흔히 라벨링 (Labeling)이 안되어 있다.
  • 그 전에 선형대수에 대해서 다루어보겠다.

  • 속력은 스칼라 값이고 속도는 벡터이다.

  • 벡터를 화살표로 정의한 이유는 들어서 옮길 수가 있기 때문에. 그래서 -를 붙이면 왔던 방향을 반대로 가는 것이다.

  • 그래서 c에서 b를 뺀다는 의미는 c에서 b만큼 왔던 방향을 되돌아간다는 의미이다.

  • 내적이란? inner product. 벡터와 벡터 or 행렬과 행렬을 곱하는 방식. xy = x(T)y. 곱한 애들을 더해서 스칼라 값이 나오게끔. 행렬의 내적 또한 이와 같은 방식으로 구할 수 있다.

  • 직선은 왜 배웠는가? 퍼셉트론과 관련이 있다. w(T)x + w0 = 0 이것은 경계선을 나타내는 수식이다.

벡터 공간

벡터의 기하학적 의미

길이가 $K$인 벡터(vector) $a$는 $K$차원의 공간에서 원점과 벡터 $a$의 값으로 표시되는 점을 연결한 화살표(arrow)로 간주할 수 있다.

$$ a = \begin{bmatrix}1 \\ 2 \end{bmatrix} $$

In [1]:
a = [1, 2]

plt.annotate('', xy=a, xytext=(0,0), arrowprops=dict(facecolor='black'))

plt.plot(0, 0, 'ro', ms=10)
plt.plot(a[0], a[1], 'ro', ms=10)

plt.text(0.35, 1.15, "$a$", fontdict={"size": 18})

plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-2.4, 3.4)
plt.ylim(-1.2, 3.2)
plt.show()


벡터의 길이

벡터 $a$ 의 길이를 놈(norm) $\| a \|$ 이라고 하며 다음과 같이 계산할 수 있다.

$$ \| a \| = \sqrt{a^T a } = \sqrt{a_1^2 + \cdots + a_K^2} $$

numpy의 linalg 서브 패키지의 norm 명령으로 벡터의 길이를 계산할 수 있다.

위에 나와있는 그림에서 화살표의 길이


In [2]:
a = np.array([4, 3])
np.linalg.norm(a)


Out[2]:
5.0

단위 벡터

길이가 1인 벡터를 단위 벡터(unit vector)라고 한다. 예를 들어 다음과 같은 벡터들은 모두 단위 벡터이다.

$$ a = \begin{bmatrix}1 \\ 0\end{bmatrix} ,\;\; b = \begin{bmatrix}0 \\ 1\end{bmatrix} ,\;\; c = \begin{bmatrix} \dfrac{1}{\sqrt{2}} \\ \dfrac{1}{\sqrt{2}} \end{bmatrix} $$

임의의 벡터 $x$에 대해 다음은 벡터는 단위 벡터가 된다.

$$ \dfrac{x}{\| x \|} $$

분모는 스칼라, 분자는 벡터


In [3]:
a = np.array([1, 0])
b = np.array([0, 1])
c = np.array([1/np.sqrt(2), 1/np.sqrt(2)])
np.linalg.norm(a), np.linalg.norm(b), np.linalg.norm(c)  #||a||, ||b||, ||c|| = 1


Out[3]:
(1.0, 1.0, 0.99999999999999989)

벡터의 합

벡터와 벡터의 합은 벡터가 된다.

$$ a = \begin{bmatrix}1 \\ 2\end{bmatrix} ,\;\; b = \begin{bmatrix}2 \\ 1\end{bmatrix} \;\;\; \rightarrow \;\;\; c = a + b = \begin{bmatrix}3 \\ 3\end{bmatrix} \;\; $$

In [4]:
a = np.array([1, 2])
b = np.array([2, 1])
c = a + b

plt.annotate('', xy=a, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.annotate('', xy=b, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.annotate('', xy=c, xytext=(0,0), arrowprops=dict(facecolor='black'))

plt.plot(0, 0, 'ro', ms=10)
plt.plot(a[0], a[1], 'ro', ms=10)
plt.plot(b[0], b[1], 'ro', ms=10)
plt.plot(c[0], c[1], 'ro', ms=10)
plt.plot([a[0], c[0]], [a[1], c[1]], 'k--')
plt.plot([b[0], c[0]], [b[1], c[1]], 'k--')

plt.text(0.35, 1.15, "$a$", fontdict={"size": 18})
plt.text(1.15, 0.25, "$b$", fontdict={"size": 18})
plt.text(1.25, 1.45, "$c$", fontdict={"size": 18})

plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.4, 4.4)
plt.ylim(-0.6, 3.8)
plt.show()


벡터의 집합 중에서 집합의 원소인 두 벡터의 선형 조합(스칼라 곱의 합)이 그 집합의 원소이면 벡터 공간이라고 한다.

$$ a, b \in \mathbf{R} \;\; \text{ and } \;\; \alpha_1a + \alpha_2b \in \mathbf{R} $$

벡터의 분해

어떤 두 벡터 $a$, $b$의 합이 다른 벡터 $c$가 될 때 $c$가 두 벡터 성분(vector component) $a$, $b$으로 분해(decomposition)된다고 말할 수 있다.

두 벡터의 내적

두 벡터의 내적은 다음과 같이 벡터의 길이 $\|a\|$, $\|b\|$ 와 두 벡터 사이의 각도 $\theta$로 계산할 수도 있다.

$$ a^Tb = \|a\|\|b\| \cos\theta $$

(증명)

위 식은 2차원 벡터의 경우 다음과 같이 증명할 수 있다.

위 그림과 같은 삼각형에서 세 변은 다음과 같은 공식을 만족한다. (코사인 법칙)

$$ \|a−b\|^2=\|a\|^2+\|b\|^2−2\|a\|\|b\|\cos\theta $$$$ \begin{eqnarray} \|a−b\|^2 &=& (a−b)^T(a−b) \\ &=& a^Ta − 2 ( a^Tb ) + b^T b \\ &=& \|a\|^2+\|b\|^2 − 2 a^T b \end{eqnarray} $$

두 식이 같으므로

$$ a^Tb = \|a\|\|b\| \cos\theta $$

벡터의 직교

두 벡터 $a$와 $b$가 이루는 각이 90도이면 서로 직교(orthogonal)라고 하며 $ a \perp b $로 표시한다.

서로 직교인 두 벡터의 벡터 내적(inner product, dot product)는 0이된다. 두 벡터의 길이가 다를 수 있다. 예를 들어 (2,2) (-1,1)이 되어도 직교를 이루며 길이가 다르다.

$$ a^T b = b^T a = 0 \;\;\;\; \leftrightarrow \;\;\;\; a \perp b $$

예를 들어 다음 두 벡터는 서로 직교한다.

$$ a = \begin{bmatrix}1 \\ 1\end{bmatrix} ,\;\; b = \begin{bmatrix}-1 \\ 1\end{bmatrix} \;\;\;\; \rightarrow \;\;\;\; a^T b = \begin{bmatrix}1 & 1\end{bmatrix} \begin{bmatrix}-1 \\ 1\end{bmatrix} = -1 + 1 = 0 $$

In [5]:
a = np.array([1, 1])
b = np.array([-1, 1])
np.dot(a, b)


Out[5]:
0

투영

벡터 $a$를 다른 벡터 $b$에 직교하는 성분 $a_1$ 와 나머지 성분 $a_2 = a - a_1$로 분해할 수 있다. 이 때 $a_2$는 $b$와 평행하며 이 길이를 벡터 $a$의 벡터 $b$에 대한 투영(projection)이라고 한다.

벡터의 투영은 다음과 같이 내적을 사용하여 구할 수 있다.

$$ a = a_1 + a_2 $$$$ a_1 \perp b \;\; \text{ and } \;\; a_2 = a - a_1 $$

이면

$$ \| a_2 \| = a^T\dfrac{b}{\|b\|} = \dfrac{a^Tb}{\|b\|} = \dfrac{b^Ta}{\|b\|} $$

이다.


In [6]:
a = np.array([1, 2])
b = np.array([2, 0])
a2 = np.dot(a, b)/np.linalg.norm(b) * np.array([1, 0])
a1 = a - a2

plt.annotate('', xy=b, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.annotate('', xy=a2, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=a1, xytext=(0,0), arrowprops=dict(facecolor='green'))

plt.plot(0, 0, 'ro', ms=10)
plt.plot(a[0], a[1], 'ro', ms=10)
plt.plot(b[0], b[1], 'ro', ms=10)

plt.text(0.35, 1.15, "$a$", fontdict={"size": 18})
plt.text(1.55, 0.15, "$b$", fontdict={"size": 18})
plt.text(-0.2, 1.05, "$a_1$", fontdict={"size": 18})
plt.text(0.50, 0.15, "$a_2$", fontdict={"size": 18})

plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.5, 3.5)
plt.ylim(-0.5, 3)
plt.show()


직선

직선은 곧 점의 집합이자 벡터의 집합이라 할 수 있다.

벡터 공간에서 직선은 다음과 같은 함수로 표현할 수 있다.

$$ f(x) = w^T(x - w) = w^Tx - w^Tw = w^Tx - \| w \|^2 = w^Tx - w_0 = 0 $$

$x$는 직선 상의 점을 나타내는 벡터이고 $w$는 원점으로부터 직선까지 이어지는 수직선을 나타내는 벡터이다. $x-w$ 벡터가 $w$ 벡터와 수직이라는 것은 $x$가 가리키는 점과 $w$가 가리키는 점을 이은 선이 $w$와 수직이라는 뜻이다.

예를 들어

$$ w = \begin{bmatrix}1 \\ 2\end{bmatrix} ,\;\; w_0 = 5 $$

일 때

$$ \begin{bmatrix}1 & 2\end{bmatrix} \begin{bmatrix}x_1 \\ x_2 \end{bmatrix} - 5 = x_1 + 2x_2 - 5 = 0 $$

이면 벡터 $w$가 가리키는 점 (1, 2)를 지나면서 벡터 $w$에 수직인 선을 뜻한다.


In [7]:
w = np.array([1, 2])
x1 = np.array([3, 1])
x2 = np.array([-1, 3])
w0 = 5

plt.annotate('', xy=w, xytext=(0,0), arrowprops=dict(facecolor='red'))
plt.annotate('', xy=x1, xytext=(0,0), arrowprops=dict(facecolor='gray'))
plt.annotate('', xy=x2, xytext=(0,0), arrowprops=dict(facecolor='gray'))

plt.plot(0, 0, 'ro', ms=10)
plt.plot(w[0], w[1], 'ro', ms=10)
plt.plot(x1[0], x1[1], 'ro', ms=10)
plt.plot(x2[0], x2[1], 'ro', ms=10)
plt.plot([-3, 5], [4, 0], 'r-', lw=5)

plt.text(0.35, 1.15, "$w$", fontdict={"size": 18})
plt.text(1.55, 0.25, "$x_1$", fontdict={"size": 18})
plt.text(-0.9, 1.40, "$x_2$", fontdict={"size": 18})

plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.7, 4.2)
plt.ylim(-0.5, 3.5)
plt.show()


직선과 점의 거리

직선 $ w^Tx - w_0 = 0 $ 과 이 직선 위에 있지 않은 점 $x'$의 거리는 단위 벡터 $\dfrac{w}{\|w\|}$에 대한 $x'$의 투영에서 $\|w\|$를 뺀 값의 절대값이다. 따라서 다음과 같이 정리할 수 있다.

$$ \left| \dfrac{w^Tx'}{\|w\|} - \|w\| \right| = \dfrac{\left|w^Tx' - \|w\|^2 \right|}{\|w\|}= \dfrac{\left|w^Tx' - w_0 \right|}{\|w\|} $$

벡터의 선형 종속과 선형 독립

벡터들의 선형 조합이 0이 되는 모두 0이 아닌 스칼라값들이 존재하면 그 벡터들은 선형 종속(linearly dependent)이라고 한다.

$$ a = \begin{bmatrix}1 \\ 2\end{bmatrix} ,\;\; b = \begin{bmatrix}3 \\ 3\end{bmatrix} \;\; c = \begin{bmatrix}10 \\ 14\end{bmatrix} \;\; $$$$ 2a + b - \frac{1}{2}c = 0 $$

In [8]:
a = np.array([1, 2])
b = np.array([3, 3])
c = np.array([10, 14])
2*a + b - 0.5*c


Out[8]:
array([ 0.,  0.])

벡터들의 선형 조합이 0이 되는 모두 0이 아닌 스칼라값들이 존재하지 않으면 그 벡터들은 선형 독립(linearly independent)이라고 한다.

$$ \alpha_1 a_1 + \cdots + \alpha_K a_K = 0 \;\;\;\; \leftrightarrow \;\;\;\; \alpha_1 = \cdots = \alpha_K = 0 $$

기저 벡터

벡터 공간에 속하는 벡터의 집합이 선형 독립이고 다른 모든 벡터 공간의 벡터들이 그 벡터 집합의 선형 조합으로 나타나면 그 벡터 집합을 벡터 공간의 기저 벡터(basis vector)라고 한다.

예를 들어 다음과 같은 두 벡터는 2차원 벡터 공간의 기저 벡터이다. $$ a = \begin{bmatrix}1 \\ 0\end{bmatrix} ,\;\; b = \begin{bmatrix}0 \\ 1\end{bmatrix} \;\; $$ 또는 $$ a = \begin{bmatrix}1 \\ 1\end{bmatrix} ,\;\; b = \begin{bmatrix}2 \\ 3\end{bmatrix} \;\; $$

다음과 같은 두 벡터는 2차원 벡터 공간의 기저 벡터가 될 수 없다. $$ a = \begin{bmatrix}1 \\ 2\end{bmatrix} ,\;\; b = \begin{bmatrix}2 \\ 4\end{bmatrix} \;\; $$

열 공간

행렬은 열 벡터의 집합으로 볼 수 있다. 이 때 열 벡터들의 조합으로 생성되는 벡터 공간을 열 공간(column space)이라고 한다.

$$ A = \begin{bmatrix} 1 & 5 & 6 \\ 2 & 6 & 8 \\ 7 & 1 & 8 \end{bmatrix} \;\;\;\; \rightarrow \;\;\;\; \alpha_1 \begin{bmatrix} 1 \\ 2 \\ 7 \end{bmatrix} + \alpha_2 \begin{bmatrix} 5 \\ 6 \\ 1 \end{bmatrix} + \alpha_3 \begin{bmatrix} 6 \\ 8 \\ 8 \end{bmatrix} \; \in \; \text{column space} $$

열 랭크

행렬의 열 벡터 중 서로 독립인 열 벡터의 최대 갯수를 열 랭크(column rank) 혹은 랭크(rank)라고 한다.

예를 들어 다음 행렬의 랭크는 2이다. 이 경우에는 inverse가 존재하지 않는다. 존재하려면 랭크가 3이어야 한다. Fullrank는 3X3에 랭크가 3일 때 풀랭크라고 한다. Full rank는 곧 역행렬이 존재한다는 의미이다.

$$ A = \begin{bmatrix} 1 & 5 & 6 \\ 2 & 6 & 8 \\ 3 & 11 & 14 \end{bmatrix} $$

numpy의 linalg 서브 패키지의 matrix_rank 명령으로 랭크를 계산할 수 있다.


In [9]:
A = np.array([[1, 5, 6], [2, 6, 8], [3, 11, 14]])
np.linalg.matrix_rank(A)


Out[9]:
2

좌표

벡터의 성분, 즉 좌표(coordinate)는 표준 기저 벡터들에 대한 해당 벡터의 투영(projection)으로 볼 수 있다.


In [10]:
e1 = np.array([1, 0])
e2 = np.array([0, 1])
a = np.array([2, 2])

plt.annotate('', xy=e1, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=e2, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=a, xytext=(0,0), arrowprops=dict(facecolor='gray'))

plt.plot(0, 0, 'ro', ms=10)
plt.plot(a[0], a[1], 'ro', ms=10)

plt.text(1.05, 1.35, "$a$", fontdict={"size": 18})
plt.text(-0.2, 0.5, "$e_1$", fontdict={"size": 18})
plt.text(0.5, -0.2, "$e_2$", fontdict={"size": 18})

plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.5, 3.5)
plt.ylim(-0.5, 3)
plt.show()
# 밑에 그림에서 보면 a가 (2,1)일 때 좌표는 (1,2)라고 한다. e1, e2와의 관게를 보면 알 수 있다.


좌표 변환

새로운 기저 벡터를에 대해 벡터 투영을 계산하는 것을 좌표 변환(coordinate transform)이라고 한다.

좌표 변환은 새로운 기저 벡터로 이루어진 변환 행렬(transform matrix) $A$ 와의 내적으로 계산한다.

$$ Aa' = a $$$$ a' = A^{-1}a $$

예를 들어, 기존의 기저 벡터가

$$ e_1 = \begin{bmatrix}1 \\ 0\end{bmatrix} ,\;\; e_2 = \begin{bmatrix}0 \\ 1\end{bmatrix} \;\; $$

이면 벡터 $a$는 사실

$$ a = \begin{bmatrix}2 \\ 2\end{bmatrix} = 2 \begin{bmatrix}1 \\ 0\end{bmatrix} + 2 \begin{bmatrix}0 \\ 1 \end{bmatrix} = 2 e_1 + 2 e_2 $$

새로운 기저 벡터가

$$ g_1 = \begin{bmatrix} \dfrac{1}{\sqrt{2}} \\ \dfrac{1}{\sqrt{2}} \end{bmatrix} ,\;\; g_2 = \begin{bmatrix} -\dfrac{1}{\sqrt{2}} \\ \dfrac{1}{\sqrt{2}} \end{bmatrix} ,\;\; $$

이면 벡터 $a$의 좌표는 다음과 같이 바뀐다.

$$ a = \begin{bmatrix}2 \\ 2\end{bmatrix} \;\;\;\; \rightarrow \;\;\;\; a' = A^{-1}a = \begin{bmatrix} e'_1 & e'_2 \end{bmatrix} a = \begin{bmatrix} \dfrac{1}{\sqrt{2}} & -\dfrac{1}{\sqrt{2}} \\ \dfrac{1}{\sqrt{2}} & \dfrac{1}{\sqrt{2}} \end{bmatrix}^{-1} \begin{bmatrix}2 \\ 2\end{bmatrix} = \begin{bmatrix} \dfrac{1}{\sqrt{2}} & \dfrac{1}{\sqrt{2}} \\ -\dfrac{1}{\sqrt{2}} & \dfrac{1}{\sqrt{2}} \end{bmatrix} \begin{bmatrix}2 \\ 2\end{bmatrix} = \begin{bmatrix}2\sqrt{2}\\0\end{bmatrix} $$

In [6]:
e1 = np.array([1, 0])
e2 = np.array([0, 1])
a = np.array([2, 2])
g1 = np.array([1, 1])/np.sqrt(2)
g2 = np.array([-1, 1])/np.sqrt(2)

plt.annotate('', xy=e1, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=e2, xytext=(0,0), arrowprops=dict(facecolor='green'))
plt.annotate('', xy=g1, xytext=(0,0), arrowprops=dict(facecolor='red'))
plt.annotate('', xy=g2, xytext=(0,0), arrowprops=dict(facecolor='red'))
plt.annotate('', xy=a, xytext=(0,0), arrowprops=dict(facecolor='gray', alpha=0.5))

plt.plot(0, 0, 'ro', ms=10)
plt.plot(a[0], a[1], 'ro', ms=10)

plt.text(1.05, 1.35, "$a$", fontdict={"size": 18})
plt.text(-0.2, 0.5, "$e_1$", fontdict={"size": 18})
plt.text(0.5, -0.2, "$e_2$", fontdict={"size": 18})
plt.text(0.2, 0.5, "$g_1$", fontdict={"size": 18})
plt.text(-0.6, 0.2, "$g_2$", fontdict={"size": 18})

plt.xticks(np.arange(-2, 4))
plt.yticks(np.arange(-1, 4))
plt.xlim(-1.5, 3.5)
plt.ylim(-0.5, 3)
plt.show()
#밑에서 a의 좌표는 2루트2,0 이라고 할 수 있다.
#좌표를 바꾼다는 것은 내가 쓰는 basis 벡터를 바꾼다는 것이다.
#독립벡터가 주어진다면 역행렬을 취해서 좌표를 구할 수 있다.



In [7]:
A = np.vstack([g1, g2]).T
A


Out[7]:
array([[ 0.70710678, -0.70710678],
       [ 0.70710678,  0.70710678]])

In [8]:
Ainv = np.linalg.inv(A)
Ainv


Out[8]:
array([[ 0.70710678,  0.70710678],
       [-0.70710678,  0.70710678]])

In [9]:
Ainv.dot(a)


Out[9]:
array([ 2.82842712,  0.        ])